package com.ld.shieldsb.common.core.queue;

import java.util.List;
import java.util.Map;
import java.util.concurrent.BlockingQueue;

import org.apache.commons.lang.StringUtils;

import com.alibaba.fastjson.JSON;
import com.ld.shieldsb.common.composition.util.SecurityUtil;
import com.ld.shieldsb.common.core.util.properties.ConfigFile;
import com.ld.shieldsb.common.core.util.properties.ConfigFileBuilder;

import lombok.extern.slf4j.Slf4j;

//自动恢复执行队列（每个程序重新启动，会自动加载上次未执行完数据，所以需要队列中数据为可以转换成json）
@Slf4j
public abstract class RecoverRunningQueue extends NoRecoverRunningQueue<String> {
    // 项目配置文件后缀（只有1个，不支持更新）
    public static final ConfigFile MARK = ConfigFileBuilder.build("mark.properties");

    private String queueName;

    // 默认创建一个队列长度为1000，线程数为1的自动运行队列
    protected RecoverRunningQueue(String queueName) {
        this(queueName, 1000);
    }

    protected RecoverRunningQueue(String queueName, int queueSize) {
        super(queueSize);
        this.queueName = queueName;
        reloadData();
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    private void reloadData() {
        String modelMapStr = MARK.getString(queueName + "_modelMap");
        String queueStr = MARK.getString(queueName + "_queue");
        if (StringUtils.isNotEmpty(modelMapStr) || StringUtils.isNotEmpty(queueStr)) {
            try {
                Map<String, String> modelMap = JSON.parseObject(modelMapStr, Map.class);
                List queue = JSON.parseArray(queueStr, QueueEntry.class);
                init(modelMap, queue);
            } catch (Exception e) {
                log.error("队列“" + queueName + "”恢复出错！", e);
            }
        }
    }

    @Override
    protected void saveQuque(BlockingQueue<QueueEntry<String>> queue) {
        MARK.save(queueName + "_queue", JSON.toJSONString(queue));
    }

    @Override
    protected void saveModelMap(Map<String, String> modelMap) {
        MARK.save(queueName + "_modelMap", JSON.toJSONString(modelMap));
    }

    public boolean put(String model) {
        try {
            String key = SecurityUtil.sha1(model);
            return put(key, model);
        } catch (Exception e) {
            log.error("", e);
            return false;
        }
    }

}
